home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 November / EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso / earcd / giochi / chinacha.lha / ChinaChallenge3 / C++ / cc3.cc < prev    next >
C/C++ Source or Header  |  1994-05-09  |  11KB  |  514 lines

  1.  
  2. //
  3. // China Challenge III - the C++ Version
  4. //
  5. // author    : Gunther Nikl
  6. // created    : 9-may-94
  7. // last change    : 9-may-94
  8. //
  9.  
  10. //
  11. // our include
  12. //
  13.  
  14. #include "cc3.h"
  15.  
  16. //
  17. // implementation
  18. //
  19.  
  20. China::China()
  21. {
  22. };
  23.  
  24. // init functions
  25.  
  26. LONG China::Init()
  27. {
  28.   LONG retval;
  29.  
  30.   if ((retval=MakeGfx()))
  31.     InitMusic();
  32.   return retval;
  33. };
  34.  
  35. LONG China::MakeGfx()
  36. {
  37.   PLANEPTR *planes;
  38.   int i;
  39.  
  40.   if ((ScrPtr=OpenScreen(&NewScreen)))
  41.   {
  42.     NewWindow.Screen=ScrPtr;
  43.     if ((WinPtr=OpenWindow(&NewWindow)))
  44.     {
  45.       SetMenuStrip(WinPtr,&MenuStrip[0]);
  46.       ShowTitle(ScrPtr,FALSE);
  47.       LoadRGB4(&ScrPtr->ViewPort,&ColorTab[0],1<<DEPTH);
  48.       InitRastPort(&RastPort);
  49.       SetFont(&RastPort,WinPtr->IFont);
  50.       InitBitMap(&BitMap,DEPTH,WIDTH,HEIGHT);
  51.       for (planes=&BitMap.Planes[0],i=DEPTH; i!=0 ; --i)
  52.        {
  53.          if (!(*planes++=AllocRaster(WIDTH,HEIGHT))) return;
  54.        }
  55.       RastPort.BitMap=&BitMap;
  56.       CurrentTime((ULONG *)&EntryTable[0],(ULONG *)&RandVal);
  57.       MakeDragon();
  58.       ScreenToFront(ScrPtr);
  59.       return 1;
  60.     }
  61.   }
  62.   /* return 0; */
  63. };
  64.  
  65. VOID China::InitMusic()
  66. {
  67.   ULONG rlen;
  68.   BPTR file;
  69.  
  70.   AudioPort.mp_Node.ln_Type=NT_MSGPORT;
  71.   if (!((BYTE)(AudioPort.mp_SigBit=AllocSignal(-1L))<0))
  72.   {
  73.     AudioPort.mp_SigTask=FindTask(NULL);
  74.     NEWLIST(&AudioPort.mp_MsgList);
  75.  
  76.     AudioIO.ioa_Request.io_Message.mn_Node.ln_Type=NT_MESSAGE;
  77.     AudioIO.ioa_Request.io_Message.mn_Node.ln_Pri=ADALLOC_MAXPREC;
  78.     AudioIO.ioa_Request.io_Message.mn_ReplyPort=&AudioPort;
  79.     AudioIO.ioa_Request.io_Flags=ADIOF_NOWAIT;
  80.     AudioIO.ioa_Data=ChannelMap;
  81.     AudioIO.ioa_Length=sizeof(ChannelMap);
  82.     if (!OpenDevice(AudioName,0,&AudioIO.ioa_Request,0))
  83.     {
  84.       AudioOpen++;
  85.       if ((SampleBuf=AllocMem(SAMPLESIZE,MEMF_CHIP|MEMF_PUBLIC)))
  86.       {
  87.         if ((file=Open((STRPTR)SampleName,MODE_OLDFILE)))
  88.         {
  89.           rlen=Read(file,SampleBuf,SAMPLESIZE);
  90.           Close(file);
  91.           if (rlen==SAMPLESIZE)
  92.           {
  93.             if (!(ciaa.ciapra & CIAF_LED))
  94.             {
  95.               ciaa.ciapra |= CIAF_LED; AudioOpen++;
  96.             }
  97.             OptMusic();
  98.             if (!AudioIO.ioa_Request.io_Error)
  99.               return;
  100.           }
  101.         }
  102.       }
  103.       FreeMusic();
  104.     }
  105.   }
  106.   MenuItems[7].Flags &= ~(CHECKED|ITEMENABLED|CHECKIT);
  107. };
  108.  
  109. // cleanup functions
  110.  
  111. VOID China::FreeMusic()
  112. {
  113.   if (AudioOpen)
  114.     CloseDevice(&AudioIO.ioa_Request);
  115.   if (SampleBuf)
  116.   {
  117.     FreeMem(SampleBuf,SAMPLESIZE); SampleBuf=NULL;
  118.     if (--AudioOpen)
  119.       ciaa.ciapra &= ~CIAF_LED;
  120.     AudioOpen=0;
  121.   }
  122. };
  123.  
  124. VOID China::CloseGfx()
  125. {
  126.   PLANEPTR *planes,p;
  127.   int i;
  128.  
  129.   for (planes=&BitMap.Planes[0],i=DEPTH; i!=0 ; i--)
  130.    {
  131.      if ((p=*planes++))
  132.        FreeRaster(p,WIDTH,HEIGHT);
  133.    }
  134.   if (WinPtr)
  135.   {
  136.     ClearMenuStrip(WinPtr); CloseWindow(WinPtr);
  137.   }
  138.   if (ScrPtr)
  139.     CloseScreen(ScrPtr);
  140. };
  141.  
  142. // main loop
  143.  
  144. VOID China::Game()
  145. {
  146.   volatile struct IntuiMessage *imsg;
  147.   ULONG imClass;
  148.   UWORD imCode;
  149.  
  150.   for (;;)
  151.    {
  152.      if (!(imsg=(struct IntuiMessage *)GetMsg(WinPtr->UserPort)))
  153.        WaitPort(WinPtr->UserPort);
  154.      else
  155.      {
  156.        imClass = imsg->Class; imCode  = imsg->Code;
  157.        ReplyMsg(&imsg->ExecMessage);
  158.        DoIDCMP(imClass,imCode);
  159.        if (EndAll)
  160.          break;
  161.      }
  162.    }
  163. };
  164.  
  165. // process all messages
  166.  
  167. VOID China::DoIDCMP(ULONG imClass, ULONG imCode)
  168. {
  169.   LONG index,pos;
  170.  
  171.   if (imClass == MENUPICK)
  172.   {
  173.     ShowTitle(ScrPtr,FALSE);
  174.     for (;;)
  175.      {
  176.        SetAPen(&ScrPtr->RastPort,4);
  177.        Move(&ScrPtr->RastPort,0,0);
  178.        Draw(&ScrPtr->RastPort,WIDTH-1,0);
  179.        if ((UWORD)imCode == MENUNULL)
  180.          break;
  181.        switch (MENUNUM(imCode))
  182.        {
  183.          case 0: switch (ITEMNUM(imCode))
  184.                  {
  185.                    case 0: ProjectAbout(); break;
  186.                    case 1: EndAll=~0; break;
  187.                  }
  188.                  break;
  189.  
  190.          case 1: switch (ITEMNUM(imCode))
  191.                  {
  192.                    case 0: MakeDragon(); break;
  193.                    case 1: OptUndoMove(); break;
  194.                    case 2: OptUndoAll(); break;
  195.                    case 3: OptLoadDragon(); break;
  196.                    case 4: OptSaveDragon(); break;
  197.                    case 5: OptMusic(); break;
  198.                  }
  199.                  break;
  200.        }
  201.        imCode=(ULONG)(ItemAddress(&MenuStrip[0],imCode))->NextSelect;
  202.        if (EndAll)
  203.          break;
  204.      }
  205.   }
  206.   else
  207.     if ((imClass==MOUSEBUTTONS) && (imCode==IECODE_LBUTTON) && (pos=CheckPos())>=0)
  208.     {
  209.       if (TwoSelected && (PiecePos2 == pos || PiecePos1 == pos))
  210.       {
  211.         index=(MAXCOUNT-PieceCount)/2; PieceCount-=2;
  212.         NewDragon.PieceTable[PiecePos1] |= 0x80; NewDragon.UndoTable[index].pos1 = PiecePos1;
  213.         NewDragon.PieceTable[PiecePos2] |= 0x80; NewDragon.UndoTable[index].pos2 = PiecePos2;
  214.         ShowDragon();
  215.       }
  216.       else
  217.       {
  218.         if (OnePiece)
  219.         {
  220.           if (PiecePos1==pos)
  221.             return;
  222.           if (NewDragon.PieceTable[PiecePos1]==NewDragon.PieceTable[pos])
  223.           {
  224.             TwoSelected=1; PiecePos2=pos;
  225.           }
  226.           else
  227.           {
  228.             OnePiece=1; PiecePos1=pos;
  229.           }
  230.         }
  231.         else
  232.         {
  233.           OnePiece=1; PiecePos1=pos;
  234.         }
  235.         DrawImage(WinPtr->RPort,&Images[NewDragon.PieceTable[pos]],(TwoSelected ? 291:3),85);
  236.       }
  237.     }
  238. };
  239.  
  240. // project function(s)
  241.  
  242. VOID China::ProjectAbout()
  243. {
  244.   struct Window *wptr;
  245.   struct RastPort *rp;
  246.   struct About *p;
  247.   int i,j;
  248.  
  249.   AboutWindow.Screen=ScrPtr;
  250.   if ((wptr=OpenWindow(&AboutWindow)))
  251.   {
  252.     rp=wptr->RPort;
  253.     SetRast(rp,5); SetBPen(rp,5);
  254.     for (i=2; i!=0; i--)
  255.      { for (p=&About1[0],j=9; j!=0; p++,j--)
  256.         {
  257.           SetAPen(rp,p->pens[i-1]); Move(rp,p->x+i-1,p->y+i-1); Text(rp,(STRPTR)&p->text[0],23);
  258.         }
  259.        SetDrMd(rp,JAM1);
  260.      }
  261.     for (i=2; i!=0; i--)
  262.       DrawImage(rp,&Images[Random(30)+1],(i==2 ? 2:168),23);
  263.     WaitPort(wptr->UserPort);
  264.     CloseWindow(wptr);
  265.   }
  266. };
  267.  
  268. // option functions
  269.  
  270. VOID China::OptUndoMove()
  271. {
  272.   LONG index;
  273.  
  274.   if ((index=(MAXCOUNT-PieceCount)/2-1)>=0)
  275.   {
  276.     PieceCount+=2;
  277.     NewDragon.PieceTable[NewDragon.UndoTable[index].pos1] &= 0x7f;
  278.     NewDragon.PieceTable[NewDragon.UndoTable[index].pos2] &= 0x7f;
  279.     ShowDragon();
  280.   }
  281. };
  282.  
  283. VOID China::OptUndoAll()
  284. {
  285.   BYTE *p;
  286.   short i;
  287.  
  288.   if (PieceCount!=MAXCOUNT)
  289.   {
  290.     PieceCount=MAXCOUNT;
  291.     for (p=&NewDragon.PieceTable[0],i=288; i!=0; *p++ &= 0x7f,i--) ;
  292.     ShowDragon();
  293.   }
  294. };
  295.  
  296. VOID China::OptLoadDragon()
  297. {
  298.   WORD header[2];
  299.   BPTR file;
  300.  
  301.   if ((file=ReqFile(0)))
  302.   {
  303.     Read(file,(APTR)&header[0],sizeof(header));
  304.     if (header[0]==0x4333)
  305.     {
  306.       PieceCount=header[1];
  307.       Read(file,&NewDragon,sizeof(struct Dragon));
  308.       ShowDragon();
  309.     }
  310.     Close(file);
  311.   }
  312. };
  313.  
  314. VOID China::OptSaveDragon()
  315. {
  316.   WORD header[2];
  317.   BPTR file;
  318.  
  319.   if ((file=ReqFile(1)))
  320.   {
  321.     header[0]=0x4333; header[1]=PieceCount;
  322.     Write(file,(APTR)&header[0],sizeof(header));
  323.     Write(file,&NewDragon,sizeof(struct Dragon));
  324.     Close(file);
  325.   }
  326. };
  327.  
  328. VOID China::OptMusic()
  329. {
  330.   struct IOAudio *areq;
  331.    BYTE OnOff;
  332.   UWORD cmd;
  333.  
  334.   if (AudioOpen)
  335.   {
  336.     OnOff=(MenuItems[7].Flags&CHECKED?~0:0);
  337.     if (Music!=OnOff)
  338.     {
  339.       areq=&AudioIO;
  340.       cmd=ADCMD_FINISH;
  341.       if (OnOff)
  342.       {
  343.         areq->ioa_Request.io_Flags=IOF_QUICK|ADIOF_PERVOL;
  344.         areq->ioa_Data=(UBYTE *)SampleBuf+104L;
  345.         areq->ioa_Length=2*51984;
  346.         areq->ioa_Period=428;
  347.         areq->ioa_Volume=55;
  348.         areq->ioa_Cycles=0;
  349.         cmd=CMD_WRITE;
  350.       }
  351.       areq->ioa_Request.io_Command=cmd;
  352.       BeginIO(&areq->ioa_Request);
  353.       Music=~Music;
  354.     }
  355.   }
  356. };
  357.  
  358. // mouseclick valid ?
  359.  
  360. LONG China::CheckPos()
  361. {
  362.   unsigned int x,y,z,d;
  363.   int i;
  364.  
  365.   for (d=1,i=3; i>=0; d+=3,i--)
  366.    {
  367.      if ( ((y=(WinPtr->MouseY-d)/30)<6) && ((x=(WinPtr->MouseX-d)/25)<12)
  368.           && (NewDragon.PieceTable[z=(6*12*i+12*y+x)]>0) )
  369.      {
  370.        if ( x==0 || x==11 || ((NewDragon.PieceTable[z-1]<=0 || NewDragon.PieceTable[z+1]<=0)
  371.             && (i==3 || NewDragon.PieceTable[12*6+z]<=0)))
  372.        {
  373.          return z;
  374.        }
  375.        break;
  376.      }
  377.    }
  378.   return -1;
  379. };
  380.  
  381. // create a new dragon
  382.  
  383. VOID China::MakeDragon()
  384. {
  385.   int i,j,k,l,pos;
  386.   UBYTE *p1,*p2;
  387.  
  388.   PieceCount=MAXCOUNT;
  389.  
  390.   for (p1=p2=&EntryTable[0],i=MAXCOUNT/4; i!=0; i--)
  391.    {
  392.      *p1++=i; *p1++=i; *p1++=i; *p1++=i;
  393.    }
  394.   for (p1=(UBYTE *)&NewDragon.PieceTable[0],j=-1,i=MAXCOUNT; i!=0; i--)
  395.    {
  396.      do
  397.      {
  398.       j++; k=(-8)&j; l=j-k; k=k>>3;
  399.      } while (!(PosTable[k]&1<<l));
  400.      pos=Random(i); p1[j]=p2[pos]; p2[pos]=p2[i-1];
  401.    }
  402.   ShowDragon();
  403. };
  404.  
  405. // random number generator
  406.  
  407. LONG China::Random(ULONG Num)
  408. {
  409.   ULONG i,j;
  410.  
  411.   i=RandVal; j=i>>12; i^=j; j=i<<20; i^=j; RandVal=i; return (i%Num);
  412. };
  413.  
  414. // draw the dragon
  415.  
  416. VOID China::ShowDragon()
  417. {
  418.   ULONG *p1;
  419.   BYTE *p2;
  420.   short n;
  421.   int i,j,k,x,y,d;
  422.  
  423.   TwoSelected=OnePiece=0;
  424.  
  425.   for (p1=&BackGroundTab[0],i=4; i!=0; i--)
  426.    {
  427.      DrawImage(&RastPort,&Images[0],p1[0],p1[1]); p1++; p1++;
  428.    }
  429.   DrawBorder(&RastPort,&Border1[0],0,0);
  430.   for (p2=&NewDragon.PieceTable[0],d=10,i=4; i!=0; d-=3,i--)
  431.     for (y=0,j=6; j!=0; y+=30,j--)
  432.       for (x=0,k=12; k!=0; x+=25,k--)
  433.         if ((n=*p2++)>0)
  434.           DrawImage(&RastPort,&Images[n],x+d,y+d);
  435.   PrintPieces();
  436.   BltBitMapRastPort(&BitMap,0,0,WinPtr->RPort,0,0,WIDTH,HEIGHT-2,0xc0);
  437. };
  438.  
  439. // print remaining pieces
  440.  
  441. VOID China::PrintPieces()
  442. {
  443.   int i;
  444.  
  445.   for (i=3; i!=0; i--)
  446.    {
  447.      SetAPen(&RastPort,APenTab[i]);
  448.      RectFill(&RastPort,278-i,51-i,312+i,60+i);
  449.    }
  450.   sprintf((STRPTR)BlankStr,(STRPTR)PieceFmt,PieceCount);
  451.   PrintIText(&RastPort,&MoveIText,0,0);
  452. };
  453.  
  454. // select a file and open the file for read or write
  455.  
  456. BPTR China::ReqFile(LONG Type)
  457. {
  458.   struct Library *ArpBase;
  459.   struct ChinaReq *req;
  460.   APTR oldwin,*wptr;
  461.   BPTR file=0;
  462.  
  463.   wptr=&((struct Process *)FindTask(NULL))->pr_WindowPtr;
  464.   oldwin=*wptr; *wptr=WinPtr; WinPtr->Flags |= RMBTRAP;
  465.   if ((req=(struct ChinaReq *)AllocMem(sizeof(struct ChinaReq),MEMF_CLEAR)))
  466.   {
  467.     if ((ArpBase=OpenLibrary(ArpName,39L)))
  468.     {
  469.       req->FReq.fr_Hail   = (!Type ? LoadDragonStr : SaveDragonStr);
  470.       req->FReq.fr_File   = &req->FileBuf;
  471.       req->FReq.fr_Dir    = &req->DirBuf;
  472.       req->FReq.fr_Window = WinPtr;
  473.       req->FReq.fr_Flags  = 0x28; /* DoColor && NewWindFunc */
  474.       req->FReq.fr_res1   = 1; /* LongPath */
  475.       req->FReq.fr_Func   = (VOID (*)())ChangeFunc;
  476.       if (FileRequest(ArpBase,&req->FReq))
  477.       {
  478.         TackOn(ArpBase,&req->DirBuf[0],&req->FileBuf[0]);
  479.         file=ArpOpen(ArpBase,&req->DirBuf[0],MODE_OLDFILE+Type);
  480.       }
  481.       CloseLibrary(ArpBase);
  482.     }
  483.     FreeMem((APTR)req,sizeof(struct ChinaReq));
  484.   }
  485.   WinPtr->Flags &= ~RMBTRAP; *wptr=oldwin;
  486.   return file;
  487. };
  488.  
  489. VOID ChangeFunc()
  490. {
  491.   __asm __volatile ("movew #10,a0@;movew #10,a0@(2)");
  492. }
  493.  
  494. //
  495. // create an instance and play ...
  496. //
  497.  
  498. int main()
  499. {
  500.   class China *CC3;
  501.  
  502.   if ((CC3=new(China)))
  503.   {
  504.     if (CC3->Init())
  505.       CC3->Game();
  506.     delete CC3;
  507.   }
  508.   return (0);
  509. };
  510.  
  511. //
  512. // end of China Challenge III - the C++ Version
  513. //
  514.